The PowerPC processor architecture has only one addressing mode for load and store instructions: register plus displacement. The general form for address operands is:
If there is no displacement, the parentheses around the register name must still be used. For example, the first two of the following statements are legal, but the last isn't:
lwz r12,4(r1)
lwz r12,(r1) ; same as displacement of 0
lwz r12,r1 ; INCORRECT
To specify an arbitrary 32-bit address, two instructions must be used, since all instructions are 32 bits long and can't contain both an opcode and a full address. A pair of instructions used to load or store data at an address falls into one of a small set of idioms, using the assembler operators lo16() , hi16() , and ha16() to isolate the required portion of the 32-bit address expression. The idioms themselves are discussed below
In specifying a 32-bit address, the desired result is that the 32-bit quantity be in a register. To do this, the high and low 16 bits of the address are entered separately with instructions suited to this task. Generally, the high 16 bits can be entered into a register with the addis (Add Immediate Shifted) operator. For example, this instruction:
addis r2,0,hi16(expr)
adds the high 16 bits of expr to 0, and enters the result into the high 16 bits of register 2. The instruction that immediately follows can then combine the low 16 bits with the high 16 bits in the register and perform whatever other operation it does (if any).
For example, to load the address of the global variable spot into general register 2, the instructions below would be used. The ori instruction doesn't sign-extend the displacement, so the high 16 bits of the address needn't be adjusted, and the hi16() assembler operator is used.
addis r2,0,hi16(spot) ; ori doesn't sign-extend
ori r2,r2,lo16(spot)
In loading the data stored at spot the lwz operator is used, which does sign-extend the displacement, the adjusted high 16 bits must be given, with the ha16() assembler operator:
addis r2,0,ha16(spot) ; lwz sign-extends
lwz r3,lo16(spot)(r2)
lwz treats the sign-extended low 16 bits as a displacement, adding it to the contents of register 2 to get a 32-bit address, and then loads the word at that address into register 3.